package com.liang.lollipop.lreader.service;

import android.animation.ValueAnimator;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.RemoteViews;

import com.liang.lollipop.lreader.MaskingView;
import com.liang.lollipop.lreader.R;
import com.liang.lollipop.lreader.activity.MainActivity;
import com.liang.lollipop.lreader.activity.SettingActivity;
import com.liang.lollipop.lreader.bean.ModelBean;
import com.liang.lollipop.lreader.drawable.MaskingDrawable;
import com.liang.lollipop.lreader.util.DensityUtil;
import com.liang.lollipop.lreader.util.ModelDAO;
import com.liang.lollipop.lreader.util.Settings;
import com.liang.lollipop.lreader.util.TaskUtils;
import com.liang.lollipop.lreader.util.ToastUtil;

import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * Created by Lollipop on 2017/07/06.
 * 蒙板服务
 */
public class MaskingService extends Service implements ValueAnimator.AnimatorUpdateListener {

    private static final String FOLLOWERS_CHANN‌​EL_ID = "com.liang.lollipop.lreader";
    public static final String FOLLOWERS_CHANN‌​EL_NAME = "LReader";

    /*---------------------------颜色切换广播组件---------------------------*/
    public static final String ACTION_FOREGROUND_CHANGE = "ACTION_FOREGROUND_CHANGE";

    public static final String ACTION_NOTIFICATION_CLICK = "ACTION_NOTIFICATION_CLICK";
    //状态栏点击时，发送过来的广播
    public static final String ARG_NOTIFICATION_CLICK_ID = "ARG_NOTIFICATION_CLICK_ID";

    /*---------------------------基本组件---------------------------*/
    //蒙版的View
    private MaskingView maskingView;
    //蒙版的绘制画板
    private MaskingDrawable maskingDrawable;
    //窗口管理器
    private WindowManager windowManager;
    //启动时的动画
    private ValueAnimator openAnimator;
    //关闭时的动画
    private ValueAnimator offAnimator;

    /*---------------------------标准功能组件---------------------------*/
    //当前的颜色（默认的颜色，在应用切换时，如果没有匹配的颜色，使用默认的颜色）
    private int targetColor = 0x22000000;
    //颜色变化的进度，仅仅用于蒙版的启动与关闭
    private float colorPrecision = 0;
    //消息通知的ID
    private static final int NOTIFICATION_ID = 548542;
    //当前所有模式的bean
    private ArrayList<ModelBean> modelBeen = new ArrayList<>();
    //
    private Handler handler = new Handler();
    //读取预设模式的工具类
    private ModelDAO modelDAO;

    /*---------------------------参数与意图的组件---------------------------*/
    //消息类型
    public static final String ARG_TYPE = "ARG_TYPE";
    //消息包含的颜色
    public static final String ARG_COLOR = "ARG_COLOR";
    //消息包含的模式ID
    public static final String ARG_ID = "ARG_ID";
    //消息用于启动
    public static final int TYPE_ON = 1;
    //消息用于关闭
    public static final int TYPE_OFF = 0;
    //消息用于改变
    public static final int TYPE_CHANGE = 2;

//    private int toggleState = STATE_OFF;

    public static final String  TILE_ACTION = "QuickSettingService";
    public static final String ARG_TILE_STATE = "ARG_STATE";

    /*---------------------------通知相关的组件---------------------------*/
    private RemoteViews notificationRemoteViews;
    private Notification notification;
    private NotificationManager notificationManager;
    private int thisSelectId = 0;

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if(SettingActivity.ACTION_SETTING_CHANGE.equals(intent.getAction())){
                initData();
            }else if(ACTION_FOREGROUND_CHANGE.equals(intent.getAction())){
                int color = intent.getIntExtra(ARG_COLOR,targetColor);
                if(maskingDrawable==null){
                    targetColor = color;
                    startMasking();
                }else{
                    maskingDrawable.smoothTo(color);
                }
                updateNotification();
            }else if(ACTION_NOTIFICATION_CLICK.equals(intent.getAction())){
                int index = intent.getIntExtra(ARG_NOTIFICATION_CLICK_ID,1)-1;
                if(index>=modelBeen.size()){
                    updateNotification();
                    return;
                }
                int thisIndex = 0;
                int clickColor = modelBeen.get(index).value;
                int clickId = modelBeen.get(index).id;

                for(int i = 0,count = modelBeen.size();i<count;i++){
                    if(modelBeen.get(i).id==thisSelectId){
                        thisIndex = i;
                    }
                }
                if(clickId==thisSelectId || (thisIndex>4 && index==5)){
                    //如果ID相同，认为是意图进入app中
                    //如果当前选中的模式为第五个以后，并且点击的为第五个，那么认为这也是合法的
                    Intent activityIntent = new Intent(context, MainActivity.class);
                    activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(activityIntent);
                }else{//点击了不同的按钮，那么认为是希望切换
                    targetColor = clickColor;
                    thisSelectId = clickId;
                    maskingDrawable.smoothTo(targetColor);
                    updateNotification();
                }
            }
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        openAnimator = new ValueAnimator();
        openAnimator.setFloatValues(0,1);
        openAnimator.addUpdateListener(this);

        offAnimator = new ValueAnimator();
        offAnimator.setFloatValues(1,0);
        offAnimator.addUpdateListener(this);

        IntentFilter filter = new IntentFilter();
        //注册设置内容变化的监听器
        filter.addAction(SettingActivity.ACTION_SETTING_CHANGE);
        //注册前台任务变化的广播监听器
        filter.addAction(ACTION_FOREGROUND_CHANGE);
        //状态栏按钮点击的广播
        filter.addAction(ACTION_NOTIFICATION_CLICK);
        registerReceiver(broadcastReceiver, filter);

        modelDAO = new ModelDAO(this);

        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O)
            createChannels();

        initData();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int type = intent.getIntExtra(ARG_TYPE,TYPE_OFF);
        try{
            switch (type){
                case TYPE_ON:
                    targetColor = intent.getIntExtra(ARG_COLOR,0x22000000);
                    thisSelectId = intent.getIntExtra(ARG_ID,0);
                    Notification notification = createNotification();
                    startForeground(NOTIFICATION_ID,notification);
                    startMasking();
                    initData();
                    break;
                case TYPE_OFF:
                    turnOff();
                    break;
                case TYPE_CHANGE:
                    int color = intent.getIntExtra(ARG_COLOR,targetColor);
                    if(maskingDrawable==null){
                        targetColor = color;
                        startMasking();
                    }else{
                        maskingDrawable.smoothTo(color);
                    }
                    updateNotification();
                    break;
            }
        }catch (Exception e){
            stopSelf();
        }
        return START_REDELIVER_INTENT;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //停止蒙版显示
        stopMasking();
        //停止并销毁启动动画
        if(openAnimator!=null)
            openAnimator.cancel();
        openAnimator = null;
        //停止并销毁关闭动画
        if(offAnimator!=null)
            offAnimator.cancel();
        offAnimator = null;
        //去除蒙版View引用
        maskingView = null;
        //去除蒙版画板的引用
        maskingDrawable = null;
        //去除窗口管理器引用
        windowManager = null;
        //注销前台任务变更的广播监听器
        unregisterReceiver(broadcastReceiver);
        //清理远程View
        notificationRemoteViews = null;
    }

    private Notification createNotificationLow(){
        Intent intent = new Intent(this,MaskingService.class);
        intent.putExtra(ARG_TYPE,TYPE_OFF);
        PendingIntent offIntent = PendingIntent.getService(this,0,intent, PendingIntent.FLAG_CANCEL_CURRENT);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this,FOLLOWERS_CHANN‌​EL_ID);
        builder.setAutoCancel(false)//可以点击通知栏的删除按钮删除
                .setPriority(NotificationCompat.PRIORITY_MAX)//最高等级的通知优先级
                .setVisibility(NotificationCompat.VISIBILITY_PRIVATE)//设置锁屏的显示模式，此处为保护模式
                .setWhen(System.currentTimeMillis())//设置消息时间
                .setSmallIcon(R.drawable.ic_visibility_white_24dp)//设置小图标
                .setOngoing(true)
        ;
        if(modelBeen.size()<2){
            builder.setContentTitle(getString(R.string.notif_title))//设置标题
                    .setContentText(getString(R.string.notif_msg))//设置内容
                    .setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
                            R.mipmap.ic_launcher)) // 设置下拉列表中的图标(大图标)
                    .setContentIntent(offIntent)//设置点击事件
            ;
        }else{
            notificationRemoteViews = new RemoteViews(getPackageName(),R.layout.notification_small);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_1,offIntent);

            //设置按钮点击的ID
            Intent btnIntent = new Intent(ACTION_NOTIFICATION_CLICK);
            btnIntent.putExtra(ARG_NOTIFICATION_CLICK_ID,1);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_2,
                    PendingIntent.getBroadcast(this,901,btnIntent,PendingIntent.FLAG_CANCEL_CURRENT));

            btnIntent = new Intent(ACTION_NOTIFICATION_CLICK);
            btnIntent.putExtra(ARG_NOTIFICATION_CLICK_ID,2);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_3,
                    PendingIntent.getBroadcast(this,902,btnIntent,PendingIntent.FLAG_CANCEL_CURRENT));

            btnIntent = new Intent(ACTION_NOTIFICATION_CLICK);
            btnIntent.putExtra(ARG_NOTIFICATION_CLICK_ID,3);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_4,
                    PendingIntent.getBroadcast(this,903,btnIntent,PendingIntent.FLAG_CANCEL_CURRENT));

            btnIntent = new Intent(ACTION_NOTIFICATION_CLICK);
            btnIntent.putExtra(ARG_NOTIFICATION_CLICK_ID,4);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_5,
                    PendingIntent.getBroadcast(this,904,btnIntent,PendingIntent.FLAG_CANCEL_CURRENT));

            btnIntent = new Intent(ACTION_NOTIFICATION_CLICK);
            btnIntent.putExtra(ARG_NOTIFICATION_CLICK_ID,5);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_6,
                    PendingIntent.getBroadcast(this,905,btnIntent,PendingIntent.FLAG_CANCEL_CURRENT));

            builder.setCustomContentView(notificationRemoteViews);
        }
        notification = builder.build();
        return notification;
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private Notification createNotificationHight(){
        Intent intent = new Intent(this,MaskingService.class);
        intent.putExtra(ARG_TYPE,TYPE_OFF);
        PendingIntent offIntent = PendingIntent.getService(this,0,intent, PendingIntent.FLAG_CANCEL_CURRENT);
        Notification.Builder builder = new Notification.Builder(this,FOLLOWERS_CHANN‌​EL_ID);
        builder.setAutoCancel(false)//可以点击通知栏的删除按钮删除
                .setPriority(Notification.PRIORITY_MAX)//最高等级的通知优先级
                .setVisibility(Notification.VISIBILITY_PRIVATE)//设置锁屏的显示模式，此处为保护模式
                .setWhen(System.currentTimeMillis())//设置消息时间
                .setSmallIcon(R.drawable.ic_visibility_white_24dp)//设置小图标
                .setColorized(true)
                .setColor(ContextCompat.getColor(this,R.color.colorPrimary))
                .setOngoing(true)
        ;
        if(modelBeen.size()<2){
            builder.setContentTitle(getString(R.string.notif_title))//设置标题
                    .setContentText(getString(R.string.notif_msg))//设置内容
                    .setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
                            R.mipmap.ic_launcher)) // 设置下拉列表中的图标(大图标)
                    .setContentIntent(offIntent)//设置点击事件
            ;
        }else{
            notificationRemoteViews = new RemoteViews(getPackageName(),R.layout.notification_small);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_1,offIntent);

            //设置按钮点击的ID
            Intent btnIntent = new Intent(ACTION_NOTIFICATION_CLICK);
            btnIntent.putExtra(ARG_NOTIFICATION_CLICK_ID,1);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_2,
                    PendingIntent.getBroadcast(this,901,btnIntent,PendingIntent.FLAG_CANCEL_CURRENT));

            btnIntent = new Intent(ACTION_NOTIFICATION_CLICK);
            btnIntent.putExtra(ARG_NOTIFICATION_CLICK_ID,2);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_3,
                    PendingIntent.getBroadcast(this,902,btnIntent,PendingIntent.FLAG_CANCEL_CURRENT));

            btnIntent = new Intent(ACTION_NOTIFICATION_CLICK);
            btnIntent.putExtra(ARG_NOTIFICATION_CLICK_ID,3);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_4,
                    PendingIntent.getBroadcast(this,903,btnIntent,PendingIntent.FLAG_CANCEL_CURRENT));

            btnIntent = new Intent(ACTION_NOTIFICATION_CLICK);
            btnIntent.putExtra(ARG_NOTIFICATION_CLICK_ID,4);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_5,
                    PendingIntent.getBroadcast(this,904,btnIntent,PendingIntent.FLAG_CANCEL_CURRENT));

            btnIntent = new Intent(ACTION_NOTIFICATION_CLICK);
            btnIntent.putExtra(ARG_NOTIFICATION_CLICK_ID,5);
            notificationRemoteViews.setOnClickPendingIntent(R.id.notification_small_btn_6,
                    PendingIntent.getBroadcast(this,905,btnIntent,PendingIntent.FLAG_CANCEL_CURRENT));

            builder.setCustomContentView(notificationRemoteViews);
        }
        notification = builder.build();
        return notification;
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void createChannels() {
        // create android channel
        NotificationChannel androidChannel = new NotificationChannel(FOLLOWERS_CHANN‌​EL_ID,
                FOLLOWERS_CHANN‌​EL_NAME, NotificationManager.IMPORTANCE_HIGH);
        // Sets whether notifications posted to this channel should display notification lights
//        androidChannel.enableLights(false);
        // Sets whether notification posted to this channel should vibrate.
//        androidChannel.enableVibration(false);
        // Sets the notification light color for notifications posted to this channel
//        androidChannel.setLightColor(ContextCompat.getColor(this,R.color.colorAccent));
        // Sets whether notifications posted to this channel appear on the lockscreen or not
        androidChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);

        notificationManager.createNotificationChannel(androidChannel);
    }

    private Notification createNotification(){
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            return createNotificationHight();
        }else {
            return createNotificationLow();
        }
    }

    private void updateNotification(){
        if(modelBeen.size()<2){
            if(notificationRemoteViews!=null){
                notificationRemoteViews = null;
                createNotification();
                notificationManager.notify(NOTIFICATION_ID,notification);
            }
            return;
        }
        if(notificationRemoteViews == null){
            createNotification();
        }

        boolean isHighlight = false;
        for(int i = 0,size = modelBeen.size()>5?5:modelBeen.size();i<5;i++){
            if(i<size){
                ModelBean bean = modelBeen.get(i);
                updateRemoteViews(i+1,bean);
                if(bean.id==thisSelectId){
                    highlightRemoteViews(i+1);
                    isHighlight = true;
                }
            }else{
                goneRemoteViews(i+1);
            }
        }

        if(!isHighlight){
            for(int i = 0,count = modelBeen.size();i<count;i++){
                if(modelBeen.get(i).id==thisSelectId){
                    int index = i>4?4:i;
                    index++;
                    modelBeen.get(i);
                    updateRemoteViews(index,modelBeen.get(i));
                    highlightRemoteViews(index);
                    break;
                }
            }
        }

        notificationManager.notify(NOTIFICATION_ID,notification);
    }

    private void goneRemoteViews(int index){
        switch (index){
            case 2:
                notificationRemoteViews.setViewVisibility(R.id.notification_small_btn_4,View.GONE);
                break;
            case 3:
                notificationRemoteViews.setViewVisibility(R.id.notification_small_btn_5,View.GONE);
                break;
            case 4:
                notificationRemoteViews.setViewVisibility(R.id.notification_small_btn_6,View.GONE);
                break;
        }
    }

    private void highlightRemoteViews(int index){
        int color = ContextCompat.getColor(this,R.color.colorAccent);
        switch (index){
            case 5:
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_icon_6,color);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_name_6,color);
                break;
            case 4:
                notificationRemoteViews.setViewVisibility(R.id.notification_small_btn_5,View.VISIBLE);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_icon_5,color);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_name_5,color);
                break;
            case 3:
                notificationRemoteViews.setViewVisibility(R.id.notification_small_btn_4,View.VISIBLE);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_icon_4,color);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_name_4,color);
                break;
            case 2:
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_icon_3,color);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_name_3,color);
                break;
            case 1:
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_icon_2,color);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_name_2,color);
                break;
        }
    }

    private void updateRemoteViews(int index,ModelBean bean){
        int color = 0xFF323232;
        switch (index){
            case 5:
                notificationRemoteViews.setViewVisibility(R.id.notification_small_btn_6,View.VISIBLE);
                notificationRemoteViews.setTextViewText(R.id.notification_small_btn_icon_6,getIcon(bean));
                notificationRemoteViews.setTextViewText(R.id.notification_small_btn_name_6,getName(bean));
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_icon_6,color);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_name_6,color);
                break;
            case 4:
                notificationRemoteViews.setViewVisibility(R.id.notification_small_btn_5,View.VISIBLE);
                notificationRemoteViews.setTextViewText(R.id.notification_small_btn_icon_5,getIcon(bean));
                notificationRemoteViews.setTextViewText(R.id.notification_small_btn_name_5,getName(bean));
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_icon_5,color);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_name_5,color);
                break;
            case 3:
                notificationRemoteViews.setViewVisibility(R.id.notification_small_btn_4,View.VISIBLE);
                notificationRemoteViews.setTextViewText(R.id.notification_small_btn_icon_4,getIcon(bean));
                notificationRemoteViews.setTextViewText(R.id.notification_small_btn_name_4,getName(bean));
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_icon_4,color);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_name_4,color);
                break;
            case 2:
                notificationRemoteViews.setTextViewText(R.id.notification_small_btn_icon_3,getIcon(bean));
                notificationRemoteViews.setTextViewText(R.id.notification_small_btn_name_3,getName(bean));
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_icon_3,color);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_name_3,color);
                break;
            case 1:
                notificationRemoteViews.setTextViewText(R.id.notification_small_btn_icon_2,getIcon(bean));
                notificationRemoteViews.setTextViewText(R.id.notification_small_btn_name_2,getName(bean));
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_icon_2,color);
                notificationRemoteViews.setTextColor(R.id.notification_small_btn_name_2,color);
                break;
        }
    }

    private String getIcon(ModelBean bean){
        if(TextUtils.isEmpty(bean.name)){
            return "";
        }
        return bean.name.substring(0,1);
    }

    private String getName(ModelBean bean){
        if(TextUtils.isEmpty(bean.name)){
            return "";
        }
        return bean.name;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    /**
     * 通过反射，获取包含虚拟键的整体屏幕高度
     *
     * @return
     */
    private Point getDisplaySize() {
        Point displaySize = new Point();
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        @SuppressWarnings("rawtypes")
        Class c;
        try {
            c = Class.forName("android.view.Display");
            @SuppressWarnings("unchecked")
            Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
            method.invoke(display, dm);
            displaySize.y = dm.heightPixels;
            displaySize.x = dm.widthPixels;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return displaySize;
    }

    private void startMasking(){

        if(offAnimator!=null)
            offAnimator.cancel();

        if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M && !android.provider.Settings.canDrawOverlays(this)){
            T(getString(R.string.toast_no_permission));
            startActivity(new Intent(android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName())));
            stopSelf();
            return;
        }

        //开始增加蒙版
        T(getString(R.string.toast_open));
        Settings.putState(this,true);
        Intent quickSettingIntent = new Intent(TILE_ACTION);
        quickSettingIntent.putExtra(ARG_TILE_STATE,TYPE_ON);
        sendBroadcast(quickSettingIntent);

        if(maskingView==null){
            maskingView = new MaskingView(this);
//            maskingView.setViewSize(getDisplaySize());
            maskingDrawable = new MaskingDrawable(targetColor);
            maskingView.setBackground(maskingDrawable);
        }

        if(maskingView.getParent()!=null){
            windowManager.removeView(maskingView);
        }
        maskingDrawable.setColor(targetColor);
        maskingDrawable.setCorners(DensityUtil.dip2px(this, Settings.getCorners(this)));
        int type = Build.VERSION.SDK_INT>=Build.VERSION_CODES.O?
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY:
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        WindowManager.LayoutParams layoutParams =
                new WindowManager.LayoutParams(
                        WindowManager.LayoutParams.MATCH_PARENT,
                        WindowManager.LayoutParams.MATCH_PARENT,
                        type,
                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE//没有焦点
                                |WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED//锁屏显示
                                |WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE//没有手势
                                |WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS//透明状态栏
                                |WindowManager.LayoutParams.FLAG_FULLSCREEN//覆盖整个屏幕
//                                |WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION//透明操作栏
                                |WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS//绘制状态栏背景
//                                |WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN//布局在整个屏幕
                                |WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
                                |WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,//允许窗口延伸到屏幕外部
//                        WindowManager.LayoutParams.FORMAT_CHANGED
                        PixelFormat.TRANSPARENT
                );
        maskingView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        windowManager.addView(maskingView,layoutParams);

        openAnimator.setFloatValues(colorPrecision,1);
        openAnimator.setDuration((long) (Settings.getDuration(this)*(1-colorPrecision)));
        openAnimator.start();

    }

    private int getNavigationBarHeight() {
        int realHeight = 0;
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        @SuppressWarnings("rawtypes")
        Class c;
        try {
            c = Class.forName("android.view.Display");
            @SuppressWarnings("unchecked")
            Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
            method.invoke(display, dm);
            realHeight = dm.heightPixels;
        } catch (Exception e) {
            e.printStackTrace();
        }
        Point point = new Point();
        display.getSize(point);
        return realHeight-point.y;
//        Resources resources = getResources();
//        int resourceId = resources.getIdentifier("navigation_bar_height","dimen", "android");
//        int height = resources.getDimensionPixelSize(resourceId);
//        return height;
    }

    private void turnOff(){

        Settings.putState(this,false);
        Intent intent = new Intent(TILE_ACTION);
        intent.putExtra(ARG_TILE_STATE,TYPE_OFF);
        sendBroadcast(intent);

        if(openAnimator!=null)
            openAnimator.cancel();

        offAnimator.setFloatValues(colorPrecision,0);
        offAnimator.setDuration((long) (Settings.getDuration(this)*colorPrecision));
        offAnimator.start();

        T(getString(R.string.toast_turn_off));

    }

    private void stopMasking(){
        //撤销删除蒙版
        T(getString(R.string.toast_stop));
        stopForeground(true);
        Settings.putState(this,false);
        Intent intent = new Intent(TILE_ACTION);
        intent.putExtra(ARG_TILE_STATE,TYPE_OFF);
        sendBroadcast(intent);
        try{
            if(maskingView!=null){
                windowManager.removeView(maskingView);
            }
        }finally {
            stopSelf();
        }
    }

    private void T(String str){
        ToastUtil.T(this,str);
    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        colorPrecision = (float) animation.getAnimatedValue();

        if(maskingView!=null&&maskingDrawable!=null){
            int color = Color.argb((int)(Color.alpha(targetColor)*colorPrecision),
                    (int)(Color.red(targetColor)*colorPrecision),
                    (int)(Color.green(targetColor)*colorPrecision),
                    (int)(Color.blue(targetColor)*colorPrecision)
            );
            maskingDrawable.setColor(color);
        }

        if(animation == offAnimator && colorPrecision == 0){
            stopSelf();
        }
    }

    private void initData(){

        TaskUtils.addTask(new TaskUtils.OnHandlerCallBack<ArrayList<ModelBean>,ModelDAO>(handler) {
            @Override
            public void onUISuccess(ArrayList<ModelBean> result) {
                modelBeen.clear();
                if(result!=null)
                    modelBeen.addAll(result);
                updateNotification();
            }

            @Override
            public void onUIError(Exception e, int code, String msg) {
            }

            @Override
            public ArrayList<ModelBean> onBackground(ModelDAO[] args) throws Exception {
                ModelDAO dao = args[0];
                return dao.selectAll();
            }
        },modelDAO);
    }

}


